const path = require('path');
const fse = require('fs-extra')
const npminstall = require('npminstall');
const pathExists = require('path-exists').sync;
const pkgDir = require('pkg-dir').sync;
const { isObject } = require('@hl-imooc-cli-dev/utils');
const formatPpath = require('@hl-imooc-cli-dev/format-path');
const { getDefaultRegistry, getNpmLatestVersion } = require("@hl-imooc-cli-dev/get-npm-info");

class Package {
    constructor(options) {
        if (!options) {
            throw new Error('package类的options参数不能为空！');
        }
        if (!isObject(options)) {
            throw new Error('package类的options参数必须为对象！');
        }
        // package 目标路径
        this.targetPath = options.targetPath;
        // package 缓存路径
        this.storeDir = options.storeDir;
        // package的name
        this.packageName = options.packageName;
        // package的Version
        this.packageVersion = options.packageVersion;
        // package的缓存目录前缀
        this.cacheFilePathPrefix = this.packageName.replace('/', '_')

    }
    async prepare() {
        if (this.storeDir && !pathExists(this.storeDir)) {
            fse.mkdirpSync(this.storeDir)
        }
        if (this.packageVersion === 'latest') {
            this.packageVersion = await getNpmLatestVersion(this.packageName)
        }

        // _@imooc-cli_init@1.1.2@@imooc-cli  
        // imooc-cli_init 1.1.2
    }
    get cacheFilePath() {
        return path.resolve(this.storeDir, `_${this.cacheFilePathPrefix}@${this.packageVersion}@${this.packageName}`)
    }
    getSpecificCacheFilePath(packageVersion) {
        return path.resolve(this.storeDir, `_${this.cacheFilePathPrefix}@${packageVersion}@${this.packageName}`)
    }
    // 判断当前package是否存在
    async exists() {
        if (this.storeDir) {
            await this.prepare()
            return pathExists(this.cacheFilePath)
        } else {
            return pathExists(this.targetPath)
        }

    }
    // 安装package
    async install() {
        
        console.log('installed', this.packageName, this.packageVersion, this.targetPath, this.storeDir)
        await this.prepare()
        const installed = npminstall({
            root: this.targetPath,
            storeDir: this.storeDir,
            registry: getDefaultRegistry(),
            pkgs: [
                { name: this.packageName, version: this.packageVersion },
            ],
        })
        return installed
    }
    // 更新package
    async update() {
        await this.prepare()
        // 1，获取最新的npm模块版本号
        const latestPackageVersion = await getNpmLatestVersion(this.packageName)
        // 2，查询最新的版本号对应的路径是否存在
        const latestFilePath = this.getSpecificCacheFilePath(latestPackageVersion)
        console.log('updateed', this.packageName, this.packageVersion, this.targetPath, this.storeDir, latestFilePath)
        // 3，如果不存在，则安装最新的版本号
        if (!pathExists(latestFilePath)) {
            await npminstall({
                root: this.targetPath,
                storeDir: this.storeDir,
                registry: getDefaultRegistry(),
                pkgs: [
                    { name: this.packageName, version: latestPackageVersion },
                ],
            })
            this.packageVersion = latestPackageVersion
        }


    }
    // 获取入口文件路径
    getRootFilePath() {
        // 1, 获取package.json 文件所在路径  - pkg-dir
        function _getRootFile(targetPath) {
            const dir = pkgDir(targetPath)
            if (dir) {
                // 2, 读取package.json -  require() js/json/node
                const pkgfile = require(path.resolve(dir, 'package.json'))
                // 3, 寻找main/lib path
                if (pkgfile && pkgfile.main) {
                    // 4, 路径的兼容(mac，windows)
                    return formatPpath(path.resolve(dir, pkgfile.main))
                }

            }
        }
        if (this.storeDir) {
            return _getRootFile(this.cacheFilePath)
        } else {
            return _getRootFile(this.targetPath)
        }
    }
}
module.exports = Package;

